//   Copyright 2012,2013 Vaughn Vernon
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package com.saasovation.common.event;

import com.saasovation.common.domain.model.DomainEvent;
import com.saasovation.common.serializer.AbstractSerializer;

/**
 * 事件序列化器
 */
public class EventSerializer extends AbstractSerializer {

    /**
     * 静态的事件序列化器
     */
    private static EventSerializer eventSerializer;

    /**
     * 获取静态同步的事件序列化器
     * @return  返回事件序列化器
     */
    public static synchronized EventSerializer instance() {
        if (EventSerializer.eventSerializer == null) {
            EventSerializer.eventSerializer = new EventSerializer();
        }

        return EventSerializer.eventSerializer;
    }

    /**
     * 以下参数构造事件序列化器
     * @param isCompact 是否紧凑
     */
    public EventSerializer(boolean isCompact) {
        this(false, isCompact);
    }

    /**
     * 使用以下参数构造事件序列化器
     * @param isPretty  是否漂亮
     * @param isCompact 是否紧凑
     */
    public EventSerializer(boolean isPretty, boolean isCompact) {
        super(isPretty, isCompact);
    }

    /**
     * 获取领域事件的序列化值
     * @param aDomainEvent  领域事件
     * @return  返回字符串
     */
    public String serialize(DomainEvent aDomainEvent) {
        String serialization = this.gson().toJson(aDomainEvent);

        return serialization;
    }

    /**
     * 反序列化
     * @param aSerialization    序列化字符串
     * @param aType             类型
     * @param <T>               泛型
     * @return  返回继承自领域事件
     */
    public <T extends DomainEvent> T deserialize(String aSerialization, final Class<T> aType) {
        T domainEvent = this.gson().fromJson(aSerialization, aType);

        return domainEvent;
    }

    /**
     * 事件序列化器
     */
    private EventSerializer() {
        this(false, false);
    }
}
